﻿using DevelopTool.Common;
using DevelopTool.Forms.CommonHelpers;
using DevelopTool.Forms.LodingForm;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Actions;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Extend;
using ICSharpCode.TextEditor.Formatting;
using ICSharpCode.TextEditor.Formatting.Intellisense;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
using ICSharpCode.TextEditor.Gui.InsightWindow;
using Sunny.UI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace DevelopTool.Forms.CommonControls.CodeEditor
{
    /// <summary>
    /// 代码编辑器控件（包装了一层ICSharpCode.TextEditor）
    /// </summary>
    public partial class CodeEditorControl : UIUserControl
    {
        #region 公有属性

        /// <summary>
        /// 编辑器文本内容
        /// </summary>
        private string contentText = string.Empty;

        /// <summary>
        /// 编辑器文本内容
        /// </summary>
        [Description("编辑器文本内容")]
        [DefaultValue(value: "")]
        [Category("DevelopTool")]
        public string ContentText
        {
            get
            {
                return this.textEditorControl.Text;
            }
            set
            {
                this.contentText = value;
                this.EditorFold(this.contentType, value);

                //还原查找窗口
                if (TextEditorGlobalData.IsShowQueryForm)
                {
                    this.textEditorQueryForm?.Dispose();
                    OpenQueryForm();
                }
            }
        }


        /// <summary>
        /// 代码类型
        /// </summary>
        private string contentType = "SQL";

        /// <summary>
        /// 代码类型
        /// </summary>
        [Description("代码类型")]
        [DefaultValue(value: "SQL")]
        [Category("DevelopTool")]
        public string ContentType
        {
            get
            {
                return this.contentType;
            }
            set
            {
                if (string.IsNullOrEmpty(value)) value = "SQL";
                this.contentType = value;
                this.combContentType.SelectedValue = value;
                this.EditorFold(value, this.contentText);
            }
        }

        /// <summary>
        /// 顶部标题
        /// </summary>
        private string panelTitle = "代码编辑器";

        /// <summary>
        /// 顶部标题
        /// </summary>
        [Description("顶部标题")]
        [DefaultValue(value: "代码编辑器")]
        [Category("DevelopTool")]
        public string PanelTitle
        {
            get
            {
                return this.panelTitle;
            }
            set
            {
                this.panelTitle = value;
                this.pnlFunction.Text = value;
            }
        }


        /// <summary>
        /// 是否显示标题
        /// </summary>        
        private int showTitle = 1;

        [Description("是否显示标题")]
        [DefaultValue(value: 1)]
        [Category("DevelopTool")]
        /// <summary>
        /// 是否显示标题
        /// </summary>
        public int ShowTitle
        {
            get
            {
                return this.showTitle;
            }
            set
            {
                this.showTitle = value;

                if (value == 2)
                {
                    pnlFunction.Collapsed = true;

                }
                else if (value == 3)
                {
                    pnlFunction.Visible = false;
                }
                else
                {
                    pnlFunction.Collapsed = false;
                }
            }
        }

        /// <summary>
        /// 是否显示顶部操作栏
        /// </summary>
        private bool showTopOperPanel = true;

        /// <summary>
        /// 是否显示顶部操作栏
        /// </summary>
        [Description("是否显示顶部操作栏")]
        [DefaultValue(value: true)]
        [Category("DevelopTool")]
        public bool ShowTopOperPanel
        {
            get
            {
                return this.showTopOperPanel;
            }
            set
            {
                this.showTopOperPanel = value;
                this.pnlFunction.ShowCollapse = value;
            }
        }

        /// <summary>
        /// 是否显示编码选择框
        /// </summary>
        private bool showEncodingCombo = false;

        /// <summary>
        /// 是否显示编码选择框
        /// </summary>
        [Description("是否显示编码选择框")]
        [DefaultValue(value: true)]
        [Category("DevelopTool")]
        public bool ShowEncodingCombo
        {
            get
            {
                return this.showEncodingCombo;
            }
            set
            {
                this.showEncodingCombo = value;
                this.combEncoding.Visible = value;//显示编码选择框
            }
        }

        /// <summary>
        /// 是否显示语言类型选择框
        /// </summary>
        private bool showContentTypeCombo = true;

        /// <summary>
        /// 是否显示语言类型选择框
        /// </summary>
        [Description("是否显示语言类型选择框")]
        [DefaultValue(value: true)]
        [Category("DevelopTool")]
        public bool ShowContentTypeCombo
        {
            get
            {
                return this.showContentTypeCombo;
            }
            set
            {
                this.showContentTypeCombo = value;
                this.combContentType.Visible = value;//显示语言类型选择框
                this.btnFormat.Enabled = value;//代码格式化按钮
            }
        }

        /// <summary>
        /// 是否启用打开文件功能
        /// </summary>
        private bool enabledOpenFile = true;

        /// <summary>
        /// 是否启用打开文件功能
        /// </summary>
        [Description("是否启用打开文件功能")]
        [DefaultValue(value: true)]
        [Category("DevelopTool")]
        public bool EnabledOpenFile
        {
            get
            {
                return this.enabledOpenFile;
            }
            set
            {
                this.enabledOpenFile = value;
                this.btnOpen.Enabled = value;
            }
        }

        /// <summary>
        /// 文本编辑器核心控件
        /// </summary>
        public TextEditorControl TextEditorControl
        {
            get
            {
                return this.textEditorControl;
            }
        }

        /// <summary>
        /// 是否显示底部字数统计
        /// </summary>
        private bool showFootWordCountPanel = false;

        /// <summary>
        /// 是否显示底部字数统计
        /// </summary>
        [Description("是否显示底部字数统计")]
        [DefaultValue(value: false)]
        [Category("DevelopTool")]
        public bool ShowFootWordCountPanel
        {
            get
            {
                return this.showFootWordCountPanel;
            }
            set
            {
                this.showFootWordCountPanel = value;
                this.pnlFoot.Visible = value;
            }
        }

        #endregion 公有属性


        #region 私有属性

        /// <summary>
        /// TextEditor文本查找扩展类
        /// </summary>
        private TextEditorQueryExtend textEditorQueryExtend;


        /// <summary>
        /// 查找窗口
        /// </summary>
        private CodeEditorQueryForm textEditorQueryForm;


        /// <summary>
        /// 当前编码类型
        /// </summary>
        private Encoding currentEncoding = Encoding.UTF8;

        /// <summary>
        /// 编辑器文本编码前的值
        /// </summary>
        private string contentTextEncodingBefore = string.Empty;

        /// <summary>
        /// 当前打开的文件对象
        /// </summary>
        private FileInfo currentFileInfo = null;

        private ICompletionDataProvider completionProvider = null;
        private InsightWindow insightWindow = null;
        private DefaultCodeCompletionWindow codeCompletionWindow = null;

        #endregion 私有属性


        #region 事件

        public delegate void OpenFileHandler(string filePath, string fileContent);


        public delegate void NeedChangeControlTitleHandler(string title);


        /// <summary>
        /// 需要改变窗口标题时触发的事件
        /// </summary>
        [Description("需要改变窗口标题时触发的事件"), Category("DevelopTool")]
        public event NeedChangeControlTitleHandler OnNeedChangeControlTitle;


        /// <summary>
        /// 打开文件事件
        /// </summary>
        [Description("打开文件事件"), Category("DevelopTool")]
        public event OpenFileHandler OnOpenFile;

        /// <summary>
        /// 编辑器内容改变事件
        /// </summary>
        [Description("编辑器内容改变事件"), Category("DevelopTool")]
        public event EventHandler ContentTextChanged;

        public delegate void VScrollBarScrollHandler(int scrollHeight, int value, object sender, ScrollEventArgs e);

        /// <summary>
        /// 编辑器滚动条滚动时触发事件
        /// </summary>
        [Description("编辑器滚动条滚动时触发事件"), Category("DevelopTool")]
        public event VScrollBarScrollHandler ScrollChanged;
               

        #endregion 事件

        public CodeEditorControl()
        {
            InitializeComponent();
        }


        private void CodeEditorControl_Load(object sender, EventArgs e)
        {
            this.textEditorQueryExtend = new TextEditorQueryExtend(this.textEditorControl);

            contentTextEncodingBefore = this.contentText;


            #region 设置按钮提示文字
            uiToolTip.SetToolTip(btnOpen, btnOpen.TipsText);
            uiToolTip.SetToolTip(btnSave, btnSave.TipsText);
            uiToolTip.SetToolTip(btnPrint, btnPrint.TipsText);
            uiToolTip.SetToolTip(btnCopy, btnCopy.TipsText);
            uiToolTip.SetToolTip(btnOpenFilePath, btnOpenFilePath.TipsText);
            uiToolTip.SetToolTip(btnFormat, btnFormat.TipsText);
            uiToolTip.SetToolTip(btnSetting, btnSetting.TipsText);
            uiToolTip.SetToolTip(btnClear, btnClear.TipsText);
            uiToolTip.SetToolTip(combContentType, combContentType.Watermark);
            uiToolTip.SetToolTip(combEncoding, combEncoding.Watermark);
            uiToolTip.SetToolTip(btnQuery, btnQuery.TipsText);
            uiToolTip.SetToolTip(btnShare, btnShare.TipsText);
            #endregion


            #region 读取配置文件并赋值

            if (this.showTitle == 1)
            {
                pnlFunction.Collapsed = Setting.TextEditor.PnlFunction_Collapsed(null, this.GetParentControl<Form>()?.GetType().FullName);
            }

            string fontFamily = Setting.TextEditor.FontFamily;
            float fontSize = Setting.TextEditor.FontSize;
            string fontStyle = Setting.TextEditor.FontStyle;
            if (!string.IsNullOrEmpty(fontFamily) && fontSize > 0)
            {
                textEditorControl.Font = new Font(fontFamily, fontSize, (FontStyle)Enum.Parse(typeof(FontStyle), fontStyle, false));
            }

            textEditorControl.ShowLineNumbers = Setting.TextEditor.ShowLineNumbers;
            textEditorControl.ShowSpaces = Setting.TextEditor.ShowSpaces;
            textEditorControl.ShowVRuler = Setting.TextEditor.ShowVRuler;
            textEditorControl.ShowHRuler = Setting.TextEditor.ShowHRuler;
            textEditorControl.ShowGuidelines = Setting.TextEditor.ShowGuidelines;
            textEditorControl.ShowTabs = Setting.TextEditor.ShowTabs;
            textEditorControl.ShowEOLMarkers = Setting.TextEditor.ShowEOLMarkers;

            textEditorControl.EnableFolding = Setting.TextEditor.ShowFold;//代码折叠
            textEditorControl.FoldMarkStyle = Setting.TextEditor.FoldMarkStyle;//折叠样式

            btnFormat.Selected = Setting.TextEditor.FormatBtn_Selected(null, this.GetParentControl<Form>()?.GetType().FullName);
            #endregion


            #region 设置操作面板位置
            foreach (Control control in pnlFunction.Controls)
            {
                control.Location = new Point(control.Location.X, 21);
            }
            #endregion

            #region 初始化语言下拉框数据

            List<dynamic> contentTypes = new List<dynamic>();
            var highlightingDefinitions = HighlightingManager.Manager.HighlightingDefinitions;
            foreach (var highlightingDefinition in highlightingDefinitions)
            {
                if (highlightingDefinition is DictionaryEntry dictionaryEntry && dictionaryEntry.Value is DictionaryEntry entry)
                {
                    if (entry.Key is SyntaxMode syntaxMode)
                    {
                        contentTypes.Add(new { text = syntaxMode.Name, value = syntaxMode.Name });
                    }
                }
            }

            combContentType.ValueMember = "value";
            combContentType.DisplayMember = "text";
            combContentType.DataSource = contentTypes;
            combContentType.SelectedValue = this.contentType;
            combContentType.SelectedValueChanged += combContentType_SelectedValueChanged;


            #endregion 初始化语言下拉框数据


            #region 初始化编码下拉框数据
            DataTable encodingDataTable = new DataTable()
            {
                Columns = {
                new DataColumn("名称", typeof(string)),
                new DataColumn("编码", typeof(string))
                }
            };
            foreach (EncodingInfo encoding in Encoding.GetEncodings())
            {
                encodingDataTable.Rows.Add(encoding.DisplayName, encoding.Name);
            }
            combEncoding.DataGridView.Init();
            combEncoding.ItemSize = new System.Drawing.Size(400, 250);
            combEncoding.DataGridView.AddColumn("名称", "名称");
            combEncoding.DataGridView.AddColumn("编码", "编码");
            combEncoding.DataGridView.ReadOnly = true;
            combEncoding.ValueChanged += delegate (object senderobj, object value)
            {
                if (value != null && value is DataGridViewRow row1)
                {
                    DataGridViewRow row = row1;
                    combEncoding.Text = row.Cells["编码"].Value.ToString();
                    currentEncoding = Encoding.GetEncoding(combEncoding.Text);
                    Encoding encoding = currentEncoding;
                    byte[] encodeBytes = encoding.GetBytes(contentTextEncodingBefore);
                    textEditorControl.Encoding = encoding;
                    textEditorControl.Text = encoding.GetString(encodeBytes);
                }
            };
            combEncoding.ShowFilter = true;
            combEncoding.DataGridView.DataSource = encodingDataTable;
            combEncoding.FilterColumnName = "编码"; //不设置则全部列过滤
            combEncoding.DataGridView.Font = new Font("宋体", 9);
            combEncoding.Text = currentEncoding.BodyName;
            #endregion 初始化编码下拉框数据


            #region 初始化代码提示图片
            Image[] images = new Image[1] { Properties.Resources.face_monkey_16px };
            imageList1.Images.AddRange(images);
            #endregion


            #region 初始化代码提示窗口
            TextAreaControl textAreaControl = textEditorControl.PrimaryTextArea;
            textAreaControl.MouseWheel += ActiveTextAreaControlMouseWheel;
            textAreaControl.ScrollBarValueChanged = (ScrollEventHandler)Delegate.Combine(textAreaControl.ScrollBarValueChanged, new ScrollEventHandler(ActiveTextAreaControl_Scroll));
            textAreaControl.TextArea.KeyEventHandler += TextArea_KeyPress;
            textAreaControl.TextArea.DoHandleMousewheel = false;
            #endregion


            if (btnFormat.Selected)//如果选中了格式化按钮，则每次都格式化
            {
                ContentFormat();
            }

            this.textEditorControl.SetHighlighting(this.textEditorControl.Document.ThemeName ?? "Default", this.contentType);

            this.textEditorControl.ActiveTextAreaControlQueryText += TextEditorControl_ActiveTextAreaControlQueryText;//触发查找事件

            this.textEditorControl.ActiveTextAreaControlSaveContent += this.TextEditorControl_ActiveTextAreaControlSaveContent;//保存内容事件

            this.Disposed += CodeEditorControl_Disposed;

            this.textEditorControl.ActiveTextAreaControl.VScrollBar.Scroll += this.VScrollBar_Scroll;
        }




        public int ScrolValue { get; set; }


        private void VScrollBar_Scroll(object sender, ScrollEventArgs e)
        {
            var vScrollBar = this.textEditorControl.ActiveTextAreaControl.VScrollBar;
            ScrollChanged?.Invoke(vScrollBar.Maximum, e.NewValue, sender, e);
        }


        private void CodeEditorControl_Disposed(object sender, EventArgs e)
        {
            if (this.textEditorQueryForm != null && this.textEditorQueryForm.IsDisposed == false)
            {
                this.textEditorQueryForm.Close();
                TextEditorGlobalData.IsShowQueryForm = false;
            }
        }


        #region 代码提示

        private bool TextArea_KeyPress(char ch)
        {
            try
            {
                if (Setting.TextEditor.ShowIntellisense)
                {
                    //目前只支持这4种语言的代码提示
                    if (contentType == "XML"
                        || contentType == "SQL"
                        || contentType == "JavaScript"
                        || contentType == "JSON")
                    {
                        ShowCompletionWindow(ch);
                    }

                }
            }
            catch (Exception)
            {
            }
            return false;
        }

        private void ActiveTextAreaControlMouseWheel(object sender, MouseEventArgs e)
        {
            TextAreaControl textAreaControl = (TextAreaControl)sender;
            if (insightWindow != null && !insightWindow.IsDisposed && insightWindow.Visible)
            {
                insightWindow.HandleMouseWheel(e);
            }
            else if (codeCompletionWindow != null && !codeCompletionWindow.IsDisposed && codeCompletionWindow.Visible)
            {
                codeCompletionWindow.HandleMouseWheel(e);
                codeCompletionWindow.Close();
            }
            else
            {
                textAreaControl.HandleMouseWheel(e);
            }
        }

        private void ActiveTextAreaControl_Scroll(object sender, ScrollEventArgs e)
        {
            if (codeCompletionWindow != null && !codeCompletionWindow.IsDisposed && codeCompletionWindow.Visible)
            {
                codeCompletionWindow.Close();
            }
        }

        private void ShowCompletionWindow(char value)
        {
            TextEditorControl editorControl = textEditorControl;
            if (completionProvider == null)
            {
                completionProvider = new DefaultCodeCompletionProvider(this.contentType, imageList1);
            }
            if (codeCompletionWindow == null)
            {
                codeCompletionWindow = DefaultCodeCompletionWindow.ShowCompletionWindow(this.GetParentControl<Form>(), editorControl, "", completionProvider, value);
                if (codeCompletionWindow != null)
                {
                    codeCompletionWindow.Closed += CloseCodeCompletionWindow;
                }
            }
            else
            {
                codeCompletionWindow.ResetCompletionData(completionProvider, textEditorControl.ActiveTextAreaControl, value);
            }
        }

        private void CloseCodeCompletionWindow(object sender, EventArgs e)
        {
        }

        #endregion


        /// <summary>
        /// 代码着色并显示折叠
        /// </summary>
        /// <param name="contentType">当前语言类型</param>
        /// <param name="contentText">编辑器内容</param>
        /// <param name="folding">是否显示折叠</param>
        private void EditorFold(string contentType, string contentText)
        {
            if (string.IsNullOrEmpty(contentText)) return;

            bool folding = Setting.TextEditor.ShowFold;
            textEditorControl.Encoding = currentEncoding;

            //  textEditorControl.Text = editorContent;
            textEditorControl.Document.TextContent = contentText;
            textEditorControl.Document.FoldingManager.ClearFoldings();
            switch (contentType.ToUpper())
            {
                case "TEXT":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new IndentFoldingStrategy();
                    }
                    break;
                case "XML":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new XmlFoldingStrategy();
                    }
                    break;
                case "SQL":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new TSQLFoldingStrategy();
                    }
                    break;
                case "JAVA":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new JavaFoldingStrategy();
                    }
                    break;
                case "JAVASCRIPT":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new JavaScriptFoldingStrategy();
                    }
                    break;
                case "JSON":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new JavaScriptFoldingStrategy();
                    }
                    break;
                case "C#":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new CSharpFoldingStrategy();
                    }
                    break;
                case "MARKDOWN":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new MarkdownFoldingStrategy();
                    }
                    break;
                case "HTML":
                case "CSHTML":
                case "ASP/XHTML":
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = new HtmlFoldingStrategy();
                    }
                    break;
                default:
                    textEditorControl.Document.FormattingStrategy = new DefaultFormattingStrategy();
                    if (folding)
                    {
                        textEditorControl.Document.FoldingManager.FoldingStrategy = null;
                    }
                    break;
            }

            if (folding)
            {
                textEditorControl.Document.FoldingManager.UpdateFoldings();

                textEditorControl.EnableFolding = Setting.TextEditor.ShowFold;//代码折叠
                textEditorControl.FoldMarkStyle = Setting.TextEditor.FoldMarkStyle;//折叠样式
            }

            textEditorControl.Document.BookmarkManager.RemoveMarks((Bookmark bookmark) => true);
            if (textEditorControl.IsIconBarVisible)
            {
                textEditorControl.IsIconBarVisible = false;
            }

            textEditorControl.ActiveTextAreaControl.AdjustScrollBars();

            textEditorControl.Document.GuidelinesManager.Update(textEditorControl.ActiveTextAreaControl.TextArea);
            textEditorControl.Invalidate();
        }

        /// <summary>
        /// 格式化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFormat_Click(object sender, EventArgs e)
        {
            ContentFormat();
            btnFormat.Selected = !btnFormat.Selected;
            Setting.TextEditor.FormatBtn_Selected(btnFormat.Selected, this.GetParentControl<Form>()?.GetType().FullName);

            if (btnFormat.Selected)
                UIMessageTip.ShowOk(this.btnFormat, "已选中格式化");
        }


        /// <summary>
        /// 格式化编辑器内容
        /// </summary>
        public void ContentFormat()
        {
            ICSharpCode.TextEditor.Formatting.IFormattingStrategy formattingStrategy = FormattingStrategyFactory.Create(this.contentType);
            this.contentText = formattingStrategy.StringFormat(textEditorControl.Text);
            EditorFold(this.contentType, this.contentText);
        }

        /// <summary>
        /// 选择语言类型
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void combContentType_SelectedValueChanged(object sender, EventArgs e)
        {
            try
            {
                if (combContentType.SelectedValue != null)
                {
                    this.contentType = combContentType.SelectedValue.ToString();
                    textEditorControl.SetHighlighting(textEditorControl.Document.ThemeName, this.contentType);
                    // EditorFold(currentContentType, textEditorControl.Text);
                    ContentFormat();
                }
            }
            catch (ArgumentOutOfRangeException)
            {
                UINotifierHelper.ShowNotifier($"未能识别文档内容为：【{combContentType.SelectedValue}】", UINotifierType.ERROR, UIStyles.CurrentResources.ErrorTitle, false, 2000);
            }
        }


        private void btnSetting_Click(object sender, EventArgs e)
        {
            new CodeEditorSettingForm(this.textEditorControl).Show();
        }

        /// <summary>
        /// 操作面板折叠
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pnlFunction_MouseClick(object sender, MouseEventArgs e)
        {
            Setting.TextEditor.PnlFunction_Collapsed(pnlFunction.Collapsed, this.GetParentControl<Form>()?.GetType().FullName);
        }

        /// <summary>
        /// 清空
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(textEditorControl.Text) && UIMessageBox.ShowMessageDialog("是否确定清空？", "提示", true, UIStyle.Orange))
            {
                ClearContent();
            }
        }

        /// <summary>
        /// 清空编辑器内容
        /// </summary>
        public void ClearContent()
        {
            new SelectWholeDocument().Execute(this.textEditorControl.ActiveTextAreaControl.TextArea);
            new Delete().Execute(this.textEditorControl.ActiveTextAreaControl.TextArea);
        }


        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen_Click(object sender, EventArgs e)
        {
            string fileName = string.Empty;
            if (!Dialogs.OpenFileDialog(ref fileName)) return;

            OpenFile(fileName);
        }

        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="filePath"></param>
        public void OpenFile(string filePath)
        {
            try
            {
                this.currentFileInfo = new FileInfo(filePath);

                string fileContent = string.Empty;

                Encoding fileEncoding = currentFileInfo.GetFileEncoding();//文件的编码

                LoadingHelper.ShowLoading("读取文件：" + currentFileInfo.Name, () =>
                {
                    fileContent = FileHelper.ReadFile(currentFileInfo.FullName, fileEncoding);//读取文件
                });

                this.btnOpenFilePath.Enabled = true;

                OnNeedChangeControlTitle?.Invoke(this.currentFileInfo.Name);


                contentTextEncodingBefore = fileContent;

                combEncoding.Enabled = true;
                combEncoding.Text = fileEncoding.BodyName;
                currentEncoding = fileEncoding;
                this.contentType = CodeEditorHelper.GetContentTypeByFileExtension(currentFileInfo.Extension);


                textEditorControl.SetHighlighting(textEditorControl.Document.ThemeName, this.contentType);
                EditorFold(this.contentType, fileContent);

                OnOpenFile?.Invoke(filePath, fileContent);

                combContentType.SelectedValue = this.contentType;
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrLog(ex);

                UIMessageBox.ShowMessageDialog(this.ParentForm, $"打开文件失败：【{ex.Message}】", "编辑器提示", showCancel: false, UIStyle.Red, false);
            }
        }


        /// <summary>
        /// 另存为
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textEditorControl.Text)) return;

            string filter = "所有格式|*.*";
            string fileName;
            if (currentFileInfo != null)
            {
                filter = currentFileInfo.Extension.ToUpper().Replace(".", "") + "|*" + currentFileInfo.Extension;
                //别把之前的文件覆盖了，另起个名字
                fileName = currentFileInfo.NameWithoutExt() + "_" + DateTime.Now.ToString("yyyyMMddHHmmss");
            }
            else
            {
                string extension = CodeEditorHelper.GetFileExtensionByContentType(this.contentType);

                if (!string.IsNullOrEmpty(pnlFunction.Text))
                {
                    fileName = pnlFunction.Text + extension;
                }
                else
                {
                    fileName = "新建文档" + extension;
                }
            }
            if (!Dialogs.SaveFileDialog(ref fileName, filter)) return;
            if (string.IsNullOrEmpty(fileName)) return;

            FileHelper.WriteFile(fileName, textEditorControl.Text, currentEncoding);

            UINotifierHelper.ShowNotifier($"保存成功", UINotifierType.OK, UIStyles.CurrentResources.OK, false, 2000);
        }


        /// <summary>
        /// 保存内容事件(Ctrl+S)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void TextEditorControl_ActiveTextAreaControlSaveContent(object sender, EventArgs e)
        {
            FileHelper.WriteFile(currentFileInfo.FullName, textEditorControl.Text, currentEncoding);
            UIMessageTip.ShowOk(textEditorControl, "保存完成");
        }

        /// <summary>
        /// 复制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCopy_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textEditorControl.Text)) return;
            Clipboard.SetText(textEditorControl.Text);
            UIMessageTip.ShowOk(this.btnCopy, "已复制到剪贴板");
        }

        /// <summary>
        /// 打开文件路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpenFilePath_Click(object sender, EventArgs e)
        {
            Dialogs.OpenDir(this.currentFileInfo.FullName);
        }



        /// <summary>
        /// 打印预览
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPrint_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textEditorControl.Text)) return;

            using (PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog())
            {
                PrintDocument printDocument = textEditorControl.PrintDocument;
                PageSettings defaultPageSettings = printDocument.DefaultPageSettings;
                printDocument.PrintController = new StandardPrintController();
                defaultPageSettings.Landscape = true;
                printPreviewDialog.StartPosition = FormStartPosition.CenterScreen;
                printPreviewDialog.Document = printDocument;
                printPreviewDialog.Document.QueryPageSettings += Document_QueryPageSettings;
                printPreviewDialog.Icon = GlobalData.MainForm.Icon;
                printPreviewDialog.ShowDialog(this);
            }

        }
        private void Document_QueryPageSettings(object sender, QueryPageSettingsEventArgs e)
        {
            e.PageSettings.Landscape = true;
            int num = -1;
            for (int i = 0; i < e.PageSettings.PrinterSettings.PaperSizes.Count; i++)
            {
                if (e.PageSettings.PrinterSettings.PaperSizes[i].PaperName == "A4")
                {
                    num = i;
                    break;
                }
            }
            if (num != -1)
            {
                e.PageSettings.PaperSize = e.PageSettings.PrinterSettings.PaperSizes[num];
            }
        }





        #region 分享
        /// <summary>
        /// 分享
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnShare_Click(object sender, EventArgs e)
        {
            btnShare.ShowContextMenuStrip(this.contextMenuStrip, 0, btnShare.Height);
        }

        private void 保存到笔记ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.textEditorControl.Text)) return;
            NoteHelper.SaveToNote(this.textEditorControl.Text, this.contentType);
        }

        private void 推送到飞书ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.textEditorControl.Text)) return;

            string text = this.textEditorControl.Text;
            Tuple<bool, string> sendResult = new Tuple<bool, string>(false, "推送失败");
            LoadingHelper.ShowLoading("正在推送内容", () =>
            {
                sendResult = FeiShuMsgHelper.SendCardMsg(text, "内容推送", contentType: this.contentType);
            });

            if (sendResult.Item1)
            {
                UINotifierHelper.ShowNotifier("推送内容成功", UINotifierType.OK, UIStyles.CurrentResources.InfoTitle, false, 2000);
            }
            else
            {
                UINotifierHelper.ShowNotifier(sendResult.Item2, UINotifierType.WARNING, UIStyles.CurrentResources.WarningTitle, false, 2000);
            }

        }
        #endregion 分享

        #region 查找

        /// <summary>
        /// 查找按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnQuery_Click(object sender, EventArgs e)
        {
            OpenQueryForm();
        }

        /// <summary>
        /// Ctrl+F 查找窗口打开
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextEditorControl_ActiveTextAreaControlQueryText(object sender, EventArgs e)
        {
            OpenQueryForm();
        }

        /// <summary>
        /// 打开查找窗口
        /// </summary>
        private void OpenQueryForm()
        {
            if (this.textEditorQueryForm == null || this.textEditorQueryForm.IsDisposed == true)
            {
                this.textEditorQueryForm = new CodeEditorQueryForm(this.textEditorControl);

            }

            this.textEditorQueryForm.Show();

            //设置查找窗口位置
            var controlPoint = this.PointToScreen(this.textEditorControl.Location);
            this.textEditorQueryForm.Location = new Point(Convert.ToInt32(controlPoint.X + (this.textEditorControl.Width / 1.5)), controlPoint.Y + 5);
        }

        /// <summary>
        /// 当前编辑器窗口关闭时，同时关闭查找窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextEditorForm_VisibleChanged(object sender, EventArgs e)
        {
            if (!this.Visible)
            {
                if (this.textEditorQueryForm != null && this.textEditorQueryForm.IsDisposed == false)
                {
                    this.textEditorQueryForm.Close();
                }
            }
        }


        /// <summary>
        /// 定位文本位置
        /// </summary>
        /// <param name="text"></param>
        /// <param name="circulate"></param>
        /// <param name="ignoreCase"></param>
        public void TextPosition(string text, bool circulate = true, bool ignoreCase = false)
        {
            textEditorQueryExtend.TextPosition(text, circulate, ignoreCase);
        }
        #endregion 查找

        /// <summary>
        /// 设置标题
        /// </summary>
        /// <param name="title"></param>
        public void SetPanelTitle(string title)
        {
            this.pnlFunction.Text = title;
        }

        /// <summary>
        /// 编辑器文本改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textEditorControl_TextAreaTextChanged(object sender, EventArgs e)
        {
            ContentTextChanged?.Invoke(sender, e);

            if (this.showFootWordCountPanel)
            {
                #region 统计文本字符数量
                int chineseCharactersCount = StringHelper.GetChineseCharactersCount(this.textEditorControl.Text);
                int englishCharactersCount = StringHelper.GetEnglishCharactersCount(this.textEditorControl.Text);
                int numberCharactersCount = StringHelper.GetNumberCharactersCount(this.textEditorControl.Text);
                int symbolCharactersCount = StringHelper.GetSymbolCharactersCount(this.textEditorControl.Text);
                int otherCharactersCount = this.textEditorControl.Text.Length - chineseCharactersCount - englishCharactersCount - numberCharactersCount - symbolCharactersCount;
                this.lblWordCountStr.Text = $"{chineseCharactersCount}中文 + {englishCharactersCount}英文 + {numberCharactersCount}数字 + {symbolCharactersCount}符号 + {otherCharactersCount}其它 = {chineseCharactersCount + englishCharactersCount + numberCharactersCount + symbolCharactersCount + otherCharactersCount}字符";
                #endregion 统计文本字符数量
            }
        }

    }
}
